#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "los_task.h"
#include "los_sem.h"

UINT32 tid_c;
UINT32 tid_p1;
UINT32 tid_p2;
UINT32 sem;

static void customer_entry(VOID) {
    UINT32 ret;

    while (1) {
		printf("customer try get sem...\n");
        // 申请信号量，无限等待
        ret = LOS_SemPend(sem, 0xffff);
        if (ret != LOS_OK) { printf("customer get sem error\n"); return ; }
		printf("customer get sem success\n");
        LOS_MDelay(1000);
    }
    return;
}

static void producer1_entry(VOID) {
	UINT32 ret;

    while (1) {
        printf("producer1 begin post sem\n");
        // 释放信号量
        ret = LOS_SemPost(sem);
		if(ret != LOS_OK){ printf("producer1 post sem error\n"); return; }
        LOS_MDelay(2000);
    }
    return;
}

static void producer2_entry(VOID) {
	UINT32 ret;

    while (1) {
        printf("producer2 begin post sem\n");
        // 释放信号量
        ret = LOS_SemPost(sem);
		if(ret != LOS_OK){ printf("producer2 post sem error\n"); return; }
        LOS_MDelay(2000);
    }
    return;
}

static UINT32 my_task(UINT32 tid, char *name, UINT16 pri, UINT32 stack_size, TSK_ENTRY_FUNC func) {
    UINT32 ret;
    TSK_INIT_PARAM_S param={0};

    // 锁住任务调度，防止高优先级任务调度
    LOS_TaskLock();
    // 任务名字
    param.pcName = name;
    // 任务入口地址
    param.pfnTaskEntry = func;
    // 任务优先级
    param.usTaskPrio = pri;
    // 任务栈
    param.uwStackSize = stack_size;
    // 调用系统函数，创建任务。成功之后任务处于就绪状态
    ret = LOS_TaskCreate(&tid, &param);
	// 创建任务失败
    if (ret != LOS_OK) { printf("create task failed, errno = %x\n", ret); }
    //解锁任务调度
    LOS_TaskUnlock();

    return ret;
}

UINT32 sem_entry(){
	UINT32 ret;

	// 创建信号量，初始状态没有资源
   	ret = LOS_SemCreate(0, &sem);
    if(ret != LOS_OK){ printf("create create sem failed\n"); return 0; }

	// 创建消费者任务
    ret = my_task(&tid_c, "customer", 9, 0x2000, customer_entry);
	if(ret != LOS_OK){ printf("create customer2 failed\n"); return -1; }
	
	// 创建生产者任务
	ret = my_task(&tid_p1, "prodecer", 10, 0x2000, producer1_entry);
	if(ret != LOS_OK){ printf("create producer1 failed\n"); return -1; }
    ret = my_task(&tid_p2, "prodecer", 10, 0x2000, producer2_entry);
	if(ret != LOS_OK){ printf("create producer2 failed\n"); return -1; }

	return ret;
}
//SYS_RUN(sem_entry);